<template>
  <div class="map">
    <div id="map_canvas" class="map-canvas"></div>
    
    <div class="map-left">
      <div class="map-left-dress">
        <div class="map-left-dress-title">
          <img src="@/assets/address.png" alt="" />
          北京
        </div>
        <div class="map-left-dress-sunny">晴转多云</div>
        <div class="map-left-dress-sunny">13°</div>
      </div>
      <div class="map-left-video">
        <div class="map-left-video-top">
          <p>{{ videoName }}</p>
        </div>
        <div class="map-left-video-middle" ref="large" v-show="showVideo">
        </div>
        <div class="map-left-video-radio" v-if="!showVideo">
          <div v-for="(item, index) in remoteStreams" :key="index">
            <p>{{ item.getId() }}</p>
          </div>
        </div>
      </div>
      <div class="map-left-user">
        <div class="map-left-user-isOnline">
          <a-checkbox>在线</a-checkbox>
          <a-checkbox>不在线</a-checkbox>
        </div>
        <div class="map-left-user-search">
          <img src="@/assets/search.png" alt="" />
          <a-input placeholder="用户名" v-model="searchValue"></a-input>
        </div>
        <div class="map-left-user-list">
          <div
            v-for="item in userItemList(searchValue)"
            :key="item.token"
            :style="
              checkedUser.find((checked) => item.account === checked.account)
                ? style
                : {}
            "
            @click="addUser(item)"
          >
            {{ item.account }}
          </div>
        </div>
      </div>
      <div class="map-left-online">
        <div @click="callBack" class="map-left-online-call">
          <img src="@/assets/call.png" alt="" style="margin-top: 15px" />
          <p
            style="
              color: #fff;
              text-align: center;
              margin-top: 10px;
              font-size: 16px;
            "
          >
            发起通话
          </p>
        </div>
        <div class="map-left-online-container" v-if="showCall">
          <img src="@/assets/container.png" alt="" />
          <div class="map-left-online-container-call">
            <p><img src="@/assets/video.png" alt="" @click="videoCall" /></p>
            <p><img src="@/assets/audio.png" alt="" @click="radioCall" /></p>
          </div>
        </div>
        <div
          class="map-left-online-mark"
          v-if="showCall"
          @click="callBack"
        ></div>
      </div>
    </div>
    <div class="map-center" v-show="remoteStreams.length && video">
      <div class="map-center-video">
        <div
          class="map-center-video-item"
          v-for="(item, index) in remoteStreams"
          :key="index"
        >
          <div
            class="map-center-video-item-video"
            ref="small"
            :data-uid="item.getId()"
          ></div>
          <div class="map-center-video-item-content">
            <p>姓名：{{ item.getId() }}</p>
            <p>单位：旅游</p>
          </div>
        </div>
      </div>
    </div>
    <div
      class="map-center-hangup"
      @click="handleOver"
      v-if="remoteStreams.length"
    >
      <img src="@/assets/hangup.png" alt="" />
    </div>
    <div class="map-right">
      <div class="map-right-title">
        <div @click="setting">绍兴市文广旅游局</div>
      </div>
      <div class="map-right-command">
        <div class="map-right-command-table">
          <div class="map-right-command-table-column">
            <div>总指挥部： 张伟明15869895236</div>
            <div>副总指挥： 张伟明15869895236</div>
          </div>
        </div>
      </div>
      <div class="map-right-event">
        <div class="map-right-event-list">
          <div class="map-right-event-list-item">
            <div class="map-right-event-list-item-name">事件名称</div>
            <div class="map-right-event-list-item-content">网易事件</div>
          </div>
          <div class="map-right-event-list-item">
            <div class="map-right-event-list-item-name">发生地点</div>
            <div class="map-right-event-list-item-content">软件园区</div>
          </div>
          <div class="map-right-event-list-item">
            <div class="map-right-event-list-item-name">发生时间</div>
            <div class="map-right-event-list-item-content">星期五</div>
          </div>
          <div class="map-right-event-list-item">
            <div class="map-right-event-list-item-name">事件等级</div>
            <div class="map-right-event-list-item-content">
              <img
                v-for="(item, index) in 4"
                :key="index"
                src="@/assets/star.png"
                alt=""
              />
            </div>
          </div>
          <div class="map-right-event-list-item">
            <div class="map-right-event-list-item-name">简单经过</div>
            <div class="map-right-event-list-item-content">
              经监测一名员工呈阳性
            </div>
          </div>
        </div>
      </div>
      <div class="map-right-task">
        <div class="map-right-task-list">
          <div
            class="map-right-task-list-item"
            v-for="(item,index) in trakList" :key="index"
          >
            <span>{{index + 1}}</span>
            <span>{{item.title}}</span>
            <span>已完成</span>
          </div>
        </div>
      </div>
    </div>
    <div class="map-answer" v-if="showAnswer">
      <p>{{ beCalledInfo.form }}来电话了</p>
      <div>
        <img src="@/assets/answer.png" @click="beCall" alt="" />
      </div>
      <div>
        <img src="@/assets/handOver.png" @click="hangup" alt="" />
      </div>
    </div>
  </div>
</template>

<script>
import WebRTC2 from "../../sdk/NIM_Web_WebRTC2_v3.7.0.js";
import { getToken } from "../../common";
import AMap from "AMap"; // 引入高德地图
import calling from "@/mixins/calling";
import netcall from "@/mixins/netcall";
import { mapState } from "vuex";
import { userList } from "@/utils/util";

export default {
  name: "mapDispatch",
  mixins: [calling, netcall],
  data() {
    return {
      map: "",
      videoList: [],
      showVideoList: false,
      config: {
        appkey: "567fa555c1aded9559ad33d06b6eca8b", // 请输入自己的appkey
        appSecret: "b9c6b5540df7", // 请输入自己的appSecret
      },
      // localUid: Math.ceil(Math.random() * 1e5),
      client: null,
      localStream: null,
      remoteStreams: [],
      max: 9,
      showAnswer: false,
      showCall: false,
      searchValue: "",
      style: {
        color: "red",
        background: "rgba(29, 69, 97)",
      },
      checkedUser: [],
      video: true,
      trakList:[
        {title: '登记红码人员信息'},
        {title: '追踪接触人员'},
        {title: '疏散群众'},
        {title: '上报卫生局'},
        {title: '实施消杀工作'},
        {title: '隔离红码人员'},
        {title: '医院收治'},
      ]
    };
  },
  mounted() {
    this.initMap();
    // this.init();
  },
  created() {
    // this.videoList.length = 9;
  },
  destroyed() {
    try {
      this.localStream.destroy();
      WebRTC2.destroy();
    } catch (e) {
      // 为了兼容低版本，用try catch包裹一下
    }
  },
  computed: {
    ...mapState(["userInfo"]),
    userItemList() {
      return (val) => {
        return userList.filter((item) => item.account.includes(val));
      };
    },
    localUid() {
      return this.userInfo.account;
    },
    videoName() {
      return this.video ? "己方视频" : "语音通话成员列表";
    },
    remoteLength() {
      return this.remoteStreams.length;
    },
    showVideo() {
      return this.video;
    },
  },
  watch: {
    remoteLength(num) {
      if (num === 0) {
        this.handleOver();
      }
    },
  },
  methods: {
    setting() {
      this.$router.push("edit");
    },
    addUser(user) {
      const num = this.checkedUser.findIndex(
        (item) => item.token === user.token
      );
      if (num >= 0) {
        this.checkedUser.splice(num, 1);
      } else {
        this.checkedUser.push(user);
      }
    },
    init() {
      console.log("初始化音视频sdk");
      window.self = this;
      this.client = WebRTC2.createClient({
        appkey: this.config.appkey,
        debug: true,
      });
      //监听事件
      this.client.on("peer-online", (evt) => {
        console.log(`${evt.uid} 加入房间`);
        this.$message.success(`${evt.uid} 加入房间`);
      });

      this.client.on("peer-leave", (evt) => {
        this.$message.success(`${evt.uid} 离开房间`);
        console.log(`${evt.uid} 离开房间`);
        this.remoteStreams = this.remoteStreams.filter(
          (item) => item.getId() !== evt.uid
        );
      });
      this.client.on("stream-added", async (evt) => {
        console.log(stream, 99999);
        const stream = evt.stream;
        const userId = stream.getId();
        if (this.remoteStreams.some((item) => item.getId() === userId)) {
          console.log("收到已订阅的远端发布，需要更新", stream);
          this.remoteStreams = this.remoteStreams.map((item) =>
            item.getId() === userId ? stream : item
          );
          await this.subscribe(stream);
        } else if (this.remoteStreams.length < this.max - 1) {
          console.log("收到新的远端发布消息", stream);
          this.remoteStreams = this.remoteStreams.concat(stream);
          await this.subscribe(stream);
        } else {
          console.warn("房间人数已满");
        }
      });
      this.client.on("stream-removed", (evt) => {
        const stream = evt.stream;
        const userId = stream.getId();
        stream.stop();
        this.remoteStreams = this.remoteStreams.map((item) =>
          item.getId() === userId ? stream : item
        );
        console.log("远端流停止订阅，需要更新", userId, stream);
      });

      this.client.on("stream-subscribed", (evt) => {
        console.log("收到了对端的流，准备播放");
        const remoteStream = evt.stream;
        //用于播放对方视频画面的div节点
        const div = [...this.$refs.small].find(
          (item) => item.dataset.uid === remoteStream.getId()
        );
        remoteStream
          .play(div)
          .then(() => {
            console.log("播放视频");
            remoteStream.setRemoteRenderMode({
              // 设置视频窗口大小
              width: 370,
              height: 220,
              cut: false, // 是否裁剪
            });
          })
          .catch((err) => {
            console.log("播放对方视频失败了: ", err);
          });
      });
      this.getToken()
        .then((token) => {
          this.joinChannel(token);
        })
        .catch((e) => {
          this.$message.success(e);
          console.error(e);
        });
    },

    getToken() {
      return getToken({
        uid: this.localUid,
        appkey: this.config.appkey,
        appSecret: this.config.appSecret,
        channelName: this.channelName,
      }).then(
        (token) => {
          return token;
        },
        (e) => {
          throw e;
        }
      );
    },
    joinChannel(token) {
      if (!this.client) {
        this.$message.success("内部错误，请重新加入房间");
        return;
      }
      console.info("开始加入房间: ", this.channelName);
      this.client
        .join({
          channelName: this.channelName,
          uid: this.localUid,
          token,
        })
        .then((data) => {
          console.info("加入房间成功，开始初始化本地音视频流");
          this.initLocalStream();
        })
        .catch((error) => {
          console.error("加入房间失败：", error);
          this.$message.success(`${error}: 请检查appkey或者token是否正确`);
          this.returnJoin();
        });
    },
    // showMyVideo() {
    //   const myVideo = document.getElementById("myVideo");
    //   let streamx;
    //   navigator.getUserMedia(
    //     {
    //       audio: true,
    //       video: { width: { exact: 640 }, height: { exact: 360 } },
    //       video: true,
    //     },
    //     function (stream1) {
    //       if (myVideo) {
    //         myVideo.srcObject = stream1;
    //         myVideo.volume = 0.0;
    //         streamx = stream1;
    //       }
    //     },
    //     function (error) {
    //       alert("第一路音视频采集失败:");
    //     }
    //   );
    // },
    initLocalStream() {
      //初始化本地的Stream实例，用于管理本端的音视频流
      this.localStream = WebRTC2.createStream({
        uid: this.localUid,
        audio: true, //是否启动mic
        video: this.showVideo, //是否启动camera
        screen: false, //是否启动屏幕共享
      });

      //设置本地视频质量
      this.localStream.setVideoProfile({
        resolution: WebRTC2.VIDEO_QUALITY_720p, //设置视频分辨率
        frameRate: WebRTC2.CHAT_VIDEO_FRAME_RATE_15, //设置视频帧率
      });
      //设置本地音频质量
      this.localStream.setAudioProfile("speech_low_quality");
      //启动媒体，打开实例对象中设置的媒体设备
      this.localStream
        .init()
        .then(() => {
          console.warn("音视频开启完成，可以播放了");
          const div = self.$refs.large;
          this.localStream.play(div);
          this.localStream.setLocalRenderMode({
            // 设置视频窗口大小
            width: div.clientWidth,
            height: div.clientHeight,
            cut: true, // 是否裁剪
          });
          // // 发布
          this.publish();
        })
        .catch((err) => {
          console.warn("音视频初始化失败: ", err);
          this.$message.warning("音视频初始化失败");
          this.localStream = null;
        });
    },
    subscribe(remoteStream) {
      remoteStream.setSubscribeConfig({
        audio: true,
        video: true,
      });
      this.client
        .subscribe(remoteStream)
        .then(() => {
          console.log("本地 subscribe 成功");
        })
        .catch((err) => {
          console.log("本地 subscribe 失败: ", err);
          this.$message.warning("订阅对方的流失败");
        });
    },
    publish() {
      console.warn("开始发布视频流");
      //发布本地媒体给房间对端
      this.client
        .publish(this.localStream)
        .then(() => {
          console.warn("本地 publish 成功");
        })
        .catch((err) => {
          console.log("本地 publish 失败: ", err);
          this.$message.warning("本地 publish 失败");
        });
    },
    setOrRelieveSilence() {
      const { isSilence } = this;
      this.isSilence = !isSilence;
      if (this.isSilence) {
        console.log("关闭mic");
        this.localStream
          .close({
            type: "audio",
          })
          .then(() => {
            console.warn("关闭 mic sucess");
          })
          .catch((err) => {
            console.log("关闭 mic 失败: ", err);
            this.$message.warning("关闭 mic 失败");
          });
      } else {
        console.log("打开mic");
        if (!this.localStream) {
          this.$message.warning("当前不能打开mic");
          return;
        }
        this.localStream
          .open({
            type: "audio",
          })
          .then(() => {
            console.log("打开mic sucess");
          })
          .catch((err) => {
            console.log("打开mic失败: ", err);
            this.$message.warning("打开mic失败");
          });
      }
    },
    stopOrOpenVideo() {
      const { isStop } = this;
      this.isStop = !isStop;
      if (this.isStop) {
        console.log("关闭摄像头");
        this.localStream
          .close({
            type: "video",
          })
          .then(() => {
            console.log("关闭摄像头 sucess");
          })
          .catch((err) => {
            console.log("关闭摄像头失败: ", err);
            this.$message.warning("关闭摄像头失败");
          });
      } else {
        console.log("打开摄像头");
        if (!this.localStream) {
          this.$message.warning("当前不能打开camera");
          return;
        }
        this.localStream
          .open({
            type: "video",
          })
          .then(() => {
            console.warn("打开摄像头 sucess");
            const div = self.$refs.large;
            this.localStream.play(div);
            this.localStream.setLocalRenderMode({
              // 设置视频窗口大小
              width: div.clientWidth,
              height: div.clientHeight,
              cut: true, // 是否裁剪
            });
          })
          .catch((err) => {
            console.log("打开摄像头失败: ", err);
            this.$message.warning("打开摄像头失败");
          });
      }
    },
    handleOver() {
      console.log("离开房间");
      // this.$message.warning("挂断");
      this.client.leave();
      this.remoteStreams = [];
      this.localStream = null;

      // this.returnJoin(1);
    },
    initMap() {
      this.map = new AMap.Map("map_canvas", {
        center: [120.582112, 29.997117], //中心点坐标
        // viewMode: "3D", //使用3D视图
        zoom: 10,
      });
      this.map.plugin(["AMap.MapType"], () => {
        //地图类型切换
        const type = new AMap.MapType({
          defaultType: 1,
          showTraffic: true,
          showRoad: true,
        });
        type.hide();
        this.map.addControl(type);
      });
      const that = this;
      AMap.plugin("AMap.DistrictSearch", function () {
        // 创建行政区查询对象
        var district = new AMap.DistrictSearch({
          // 返回行政区边界坐标等具体信息
          extensions: "all",
          // 设置查询行政区级别为 区
          level: "city",
        });
        const districtList = [
          "绍兴市",
          "上虞区",
          "越城区",
          "诸暨",
          "新昌",
          "柯桥",
          "嵊州",
        ];
        districtList.map((item) => {
          district.search(item, (status, result) => {
            // 获取朝阳区的边界信息
            const bounds = result.districtList[0].boundaries;
            const polygons = [];
            if (bounds) {
              for (var i = 0, l = bounds.length; i < l; i++) {
                //生成行政区划polygon
                const polygon = new AMap.Polygon({
                  map: that.map,
                  strokeWeight: 1,
                  path: bounds[i],
                  fillOpacity: 0.7,
                  fillColor: "rgba(0, 41, 75, 0.7)",
                  strokeColor: "rgba(103, 189, 250)",
                });
                polygons.push(polygon);
              }
              // 地图自适应
              // that.map.setFitView();
            }
          });
        });
      });
    },
    callBack() {
      // if (!this.remoteStreams.length) {
      this.showCall = !this.showCall;
      // }
      // this.$message.warning("当前正在通话中");
    },
  },
};
</script>

<style lang="less" scoped>
@primary-color: rgba(0, 41, 75, 0.8);
.map {
  width: 100%;
  height: 100%;
  &-canvas {
    width: 100%;
    height: 100%;
  }
  &-top {
    width: 100%;
    height: 50px;
    position: absolute;
    top: 0;
    background: #fff;
  }
  &-left {
    position: absolute;
    top: 10px;
    left: 20px;
    width: 410px;
    height: calc(100% - 30px);
    &-dress {
      // width: 60%;
      height: 45px;
      border-radius: 20px;
      display: flex;
      color: #fff;
      font-size: 16px;
      // justify-content: space-around;
      line-height: 40px;
      background: url(~@/assets/weather.png) 100% 100% no-repeat;
      &-title {
        margin-left: 20px;
      }
      &-sunny {
        margin-left: 40px;
      }
    }
    &-video {
      margin-top: 10px;
      width: 100%;
      height: 338px;
      // border: 1px solid rgba(103, 189, 250);
      background: url(~@/assets/myVideo.png) 100% 100% no-repeat;
      &-top {
        width: 100%;
        height: 35px;
        padding-left: 15px;
        line-height: 35px;
        // background: rgba(0, 41, 75);
        position: relative;
        p {
          position: absolute;
          top: 0;
          color: #fff;
          padding-left: 10px;
        }
        img {
          height: 100%;
          width: 100%;
        }
      }
      &-middle {
        // background: rgba(0, 41, 75, 0.7);
        height: calc(100% - 35px);
        video {
          width: 100%;
          height: 100%;
        }
      }
      &-radio {
        background: rgba(0, 41, 75, 0.7);
        height: calc(100% - 35px);
        overflow: auto;
        color: #fff;
        div {
          width: 50%;
          padding: 5px 10px;
          height: 25px;
          display: inline-block;
          p {
            border-bottom: 1px solid rgba(87, 163, 255);
          }
        }
      }
    }
    &-user {
      height: 413px;
      width: 100%;
      background: url(~@/assets/personner.png) 100% 100% no-repeat;
      margin-top: 5px;
      color: #fff;
      padding: 10px 20px;
      &-isOnline {
        height: 60px;
        text-align: right;
        line-height: 60px;
      }
      &-search {
        height: 30px;
        position: relative;
        color: #fff;
        img {
          position: absolute;
          left: 10px;
          top: 5px;
          z-index: 2;
          height: 20px;
        }
        input {
          background: rgba(0, 41, 75);
          color: #fff;
          text-indent: 25px;
          height: 30px;
          border-radius: 25px;
          border: 1px solid rgba(29, 69, 97);
        }
      }
      &-list {
        height: 275px;
        overflow: auto;
        padding: 0px 20px;
        div {
          height: 25px;
          line-height: 25px;
          cursor: pointer;
          &:hover {
            background: rgba(29, 69, 97);
          }
        }
      }
    }
    &-online {
      height: 150px;
      width: 50%;
      background: rgba(0, 41, 75, 0.7);
      border-radius: 20px;
      display: flex;
      margin: auto;
      position: relative;
      margin-top: 10px;

      &-call {
        margin: auto;
        cursor: pointer;
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        z-index: 2;
      }
      &-container {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(4%, -45%);
        z-index: 1;
        &-call {
          position: absolute;
          top: 50%;
          left: 60%;
          transform: translate(-50%, -50%);
          img {
            cursor: pointer;
          }
        }
      }
      &-mark {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        right: 0;
      }
    }
  }
  &-center {
    position: absolute;
    max-width: 65%;
    left: 30%;
    max-height: calc(100% - 120px);
    top: 100px;
    z-index: 10;
    &-video {
      width: 100%;
      height: 100%;
      display: flex;
      flex-wrap: wrap;
      &-item {
        width: 370px;
        height: 250px;
        margin-right: 20px;
        margin-top: 20px;
        background: rgba(15, 113, 231, 0.8);
        &-video {
          height: 85%;
          width: 100%;
        }
        &-content {
          height: 15%;
          display: FLEX;
          font-size: 18px;
          color: #fff;
          background: rgba(3, 111, 234);
          p {
            height: 100%;
            width: 50%;
            overflow: hidden;
            padding: 5px 10px;
          }
        }
      }
    }
    &-hangup {
      position: fixed;
      bottom: 30px;
      left: 50%;
    }
  }
  &-answer {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: rgba(0, 41, 75);
    color: #fff;
    padding: 20px;

    div {
      display: inline-block;
      width: 80px;
      img {
        width: 100%;
        cursor: pointer;
      }
      &:nth-child(2) {
        margin-right: 20px;
      }
    }
  }
  &-right {
    position: absolute;
    top: 30px;
    right: 20px;
    width: 404px;
    color: #fff;
    height: calc(100% - 30px);
    &-title {
      width: 100%;
      height: 35px;
      line-height: 35px;
      display: flex;
      justify-content: flex-end;
      div {
        width: 40%;
        background: @primary-color;
        margin: right;
        padding-left: 15px;
      }
    }
    &-command {
      height: 192px;
      background: url(~@/assets/command.png);
      width: 100%;
      margin-top: 30px;
      padding: 20px;
      &-title {
        text-align: center;
        height: 35px;
      }
      &-table {
        height: 60px;
        margin-top: 60px;
        margin-left: 50px;
        &-column {
          line-height: 30px;
          border-radius: 4px;
          padding: 5px;
        }
        &-data {
          display: flex;
          background: rgba(2, 91, 193);
          padding: 5px;
          border-radius: 5px;
          &-left {
            flex: 2;
          }
          &-right {
            flex: 8;
            span {
              display: inline-block;
              width: 25%;
            }
          }
        }
      }
    }
    &-event {
      width: 100%;
      height: 268px;
      background: url(~@/assets/event.png);
      margin-top: 15px;
      padding: 20px;
      &-title {
        text-align: center;
        height: 35px;
      }
      &-list {
        margin-top: 35px;
        &-item {
          display: flex;
          border: 1px solid rgba(16, 81, 149);
          margin-bottom: 10px;
          height: 30px;
          line-height: 30px;
          &-name {
            background: rgba(15, 83, 196);
            text-align: center;
            padding: 0 10px;
            margin-right: 10px;
          }
        }
      }
    }
    &-task {
      width: 100%;
      height: 409px;
      background: url(~@/assets/task.png);
      margin-top: 15px;
      padding: 20px;
      &-title {
        text-align: center;
        height: 35px;
      }
      &-list {
        margin-top: 40px;
        margin-left: 15px;
        &-item {
          height: 30px;
          border: 1px solid rgba(15, 83, 196);
          margin-bottom: 3px;
          line-height: 30px;
          display: flex;
          span {
            flex: 2;
            text-align: center;
            &:last-child {
              flex: 2;
              color: rgba(1, 246, 247);
            }
            &:nth-child(2){
              text-align: left;
              flex: 6;
            }
          }
        }
      }
    }
  }
}
::-webkit-scrollbar {
  width: 0 !important;
}
.ant-checkbox-wrapper {
  color: #fff;
}
body {
  overflow: hidden;
}
</style>